package org.xx.armory.objectparser;

import java.util.Objects;

import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.xx.armory.commons.Validators.greaterThanOrEqual;

/**
 * 文件的位置信息, 包括行号和列号。
 *
 * @author Haart
 */
public final class LineInfo {
    /**
     * 表示未知的文件位置信息。
     */
    public static final LineInfo UNKNOWN = new LineInfo("?", 0, 0);
    private final String path;
    private final int rowNumber;
    private final int colNumber;

    /**
     * 构造文件的位置信息。
     *
     * @param path
     *         文件全路径。
     * @param rowNumber
     *         行号。
     * @param colNumber
     *         列号。
     * @throws IllegalArgumentException
     *         如果参数{@code rowNumber}小于{@code 0}或者参数{@code colNumber}小于{@code 0}。
     */
    public LineInfo(
            final String path,
            final int rowNumber,
            final int colNumber
    ) {
        greaterThanOrEqual(rowNumber, "rowNumber", 0);
        greaterThanOrEqual(colNumber, "colNumber", 0);

        this.path = isBlank(path) ? "?" : path.trim();
        this.rowNumber = rowNumber;
        this.colNumber = colNumber;
    }

    /**
     * 获取源文件全路径。
     *
     * @return 源文件全路径。
     */
    public final String getPath() {
        return this.path;
    }

    /**
     * 获取行号。
     *
     * @return 行号。
     */
    public final int getRowNumber() {
        return this.rowNumber;
    }

    /**
     * 获取列号。
     *
     * @return 列号。
     */
    public final int getColNumber() {
        return this.colNumber;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return Objects.hash(this.path, this.rowNumber, this.colNumber);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        LineInfo other = (LineInfo) obj;
        return Objects.equals(this.path, other.path) && this.rowNumber == other.rowNumber && this.colNumber == other.colNumber;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "LineInfo{path=" + path + ", rowNumber=" + rowNumber + ", colNumber=" + colNumber + "}";
    }
}
